var DBFactory = require('../db/mysql');
var async = require('async');
var PostHelper = require('./../util/postHelper');
var ArticleDao = module.exports;

ArticleDao.searchArticle = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = "select id, title, content, gist, labels, DATE_FORMAT(created_date, '%Y-%m-%d %H:%i:%s') as created_date, author, read_count, uniquekey, url, status from article where status in(1, 2) and title like ?";
                var value = ['%' + data.keyword + '%'];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    var del_info = result && result.length > 0 ? result : null;

                    if (!del_info) {
                        return callback('未找到文章记录!');
                    }

                    if (del_info.labels) {
                        del_info.labels = [del_info.labels];
                    }

                    return callback(null, del_info);
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article_info => {
                    var sql = 'select count(*) as count from article_stars where article_id = ?';
                    var value = [article_info.id];
                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article_info.starsCount = result[0].count;
                        info.push(article_info);

                        if (info.length == release_info.length) {
                            callback(null, release_info);
                        }
                    });
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article_info => {
                    var sql = 'select count(*) as count from article_comment where article_id = ?';
                    var value = [article_info.id];
                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        } else {
                            article_info.CommentCount = result[0].count;
                            info.push(article_info);

                            if (info.length == release_info.length) {
                                callback(null, true, release_info);
                            }
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.keywordSearchArticle = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = "select id, title, content, gist, labels, DATE_FORMAT(created_date, '%Y-%m-%d %H:%i:%s') as created_date, author, read_count, uniquekey, url, status from article where status in(1, 2)";
                var value = [];
                data.cateUrl == '全部' ? sql += ' order by created_date desc limit ?, ?' : sql += "and labels like ? order by created_date desc limit ?, ?"
                data.cateUrl == '全部' ? value = [(parseInt(data.page) - 1) * parseInt(data.size), parseInt(data.size)] : value = ['%' + data.cateUrl + '%', (parseInt(data.page) - 1) * parseInt(data.size), parseInt(data.size)]

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    var del_info = result && result.length > 0 ? result : null;

                    if (!del_info) {
                        return callback('未找到文章记录!');
                    }

                    if (del_info.labels) {
                        del_info.labels = [del_info.labels];
                    }

                    return callback(null, del_info);
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article_info => {
                    var sql = 'select count(*) as count from article_stars where article_id = ?';
                    var value = [article_info.id];
                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article_info.starsCount = result[0].count;
                        info.push(article_info);

                        if (info.length == release_info.length) {
                            callback(null, release_info);
                        }
                    });
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article_info => {
                    var sql = 'select count(*) as count from article_comment where article_id = ?';
                    var value = [article_info.id];
                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        } else {
                            article_info.CommentCount = result[0].count;
                            info.push(article_info);

                            if (info.length == release_info.length) {
                                callback(null, true, release_info);
                            }
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.categories = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = "select labels from article where labels is not null group by labels";
                var value = [];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    var del_info = result && result.length > 0 ? result : null;

                    if (!del_info) {
                        return callback('未找到文章记录!');
                    }

                    callback(null, del_info);
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article_info => {
                    var sql = 'select count(*) as count from article where labels = ?';
                    var value = [article_info.labels];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article_info.articleCount = result[0].count;
                        info.push(article_info);

                        if (info.length == release_info.length) {
                            callback(null, true, release_info);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getArticleList = function (data, cb) {
    if (!data) {
        cb(new Error(500));
    } else {
        DBFactory.getConnection(function (error, connection) {
            if (error) {
                cb(error);
            } else {
                async.waterfall([
                    // 开始Transaction
                    function (callback) {
                        connection.beginTransaction(function (err) {
                            callback(err);
                        });
                    },
                    function (callback) {
                        var sql = 'select id, title, content, gist, labels, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date, author, read_count, status, main_pic from article where status in(1, 2) order by created_date desc limit ?, ?';
                        var value = [(parseInt(data.page) - 1) * parseInt(data.size), parseInt(data.size)];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                cb(null, {
                                    status: 201,
                                    msg: err
                                });
                            } else {
                                var del_info = result && result.length > 0 ? result : null;

                                if (!del_info) {
                                    connection.release();
                                    cb(null, {
                                        status: 201,
                                        msg: '未找到文章记录!'
                                    });
                                } else {
                                    if (del_info.labels) {
                                        del_info.labels = [del_info.labels];
                                    }

                                    callback(null, {
                                        status: 200,
                                        article: del_info
                                    });
                                }
                            }
                        });
                    },
                    function (release_info, callback) {
                        var sql = 'select count(*) as count from article';
                        var value = [];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                cb(null, {
                                    status: 201,
                                    msg: err
                                });
                            } else {
                                data.articleCount = result[0].count;

                                callback(null, {
                                    status: 200,
                                    release_info: release_info
                                });
                            }
                        });
                    },
                    function (release_info, callback) {
                        var info = [];
                        release_info.release_info.article.forEach(article_info => {
                            var sql = 'select count(*) as count from article_stars where article_id = ?';
                            var value = [article_info.id];
                            connection.query(sql, value, function (err, result) {
                                if (err) {
                                    cb(null, {
                                        status: 201,
                                        msg: err
                                    });
                                } else {
                                    article_info.starsCount = result[0].count;
                                    info.push(article_info);

                                    if (info.length == release_info.release_info.article.length) {
                                        callback(null, {
                                            status: 200,
                                            article: info
                                        });
                                    }
                                }
                            });
                        });
                    },
                    function (release_info, callback) {
                        var info = [];
                        release_info.article.forEach(article_info => {
                            var sql = 'select count(*) as count from article_comment where article_id = ?';
                            var value = [article_info.id];
                            connection.query(sql, value, function (err, result) {
                                if (err) {
                                    cb(null, {
                                        status: 201,
                                        msg: err
                                    });
                                } else {
                                    article_info.CommentCount = result[0].count;
                                    info.push(article_info);

                                    if (info.length == release_info.article.length) {
                                        callback(null, true, {
                                            status: 200,
                                            article: info,
                                            articleCount: data.articleCount
                                        });
                                    }
                                }
                            });
                        });
                    }
                ], function (DbErr, isSuccess, uidOrInfo) {
                    if (DbErr || !isSuccess) {
                        connection.rollback(function () {
                            connection.release();
                        });

                        return cb(DbErr);
                    }

                    connection.commit(function (e) {
                        if (e) {
                            connection.rollback(function () {
                                connection.release();
                            });

                            return cb(e);
                        }

                        connection.release();
                        cb(null, uidOrInfo);
                    });
                });
            }
        });
    }
}

ArticleDao.articleDetail = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'select id, title, content, gist, labels, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date, author, read_count, avatar, openid from article where id = ?';
                var value = [data];
                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    } else {
                        var del_info = result && result.length > 0 ? result[0] : null;

                        if (!del_info) {
                            return callback('未找到文章记录!');
                        }

                        callback(null, del_info);
                    }
                });
            },
            function (release_info, callback) {
                var sql = 'select count(*) as count from article_stars where article_id = ?';
                var value = [release_info.id];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    release_info.starsCount = result[0].count;
                    return callback(null, release_info);
                });
            },
            function (release_info, callback) {
                var sql = 'select count(*) as count from article_comment where article_id = ?';
                var value = [release_info.id];
                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    release_info.CommentCount = result[0].count;
                    return callback(null, true, release_info);
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getUserArticleList = function (data, cb) {
    var sql = 'select id, title, content, gist, labels, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date, author, url, uniquekey from article where account = ? and app_sid = ? order by created_date desc';
    var value = [data.account, data.app_sid];

    DBFactory.executeSql(sql, value, 'ArticleDao.getUserArticleList', autoCbErrFunction(cb, function (result) {
        var del_info = result && result.length > 0 ? result : null;

        if (!del_info) {
            cb(null, {
                status: 201,
                msg: '未找到文章记录!'
            });
        } else {
            if (del_info.labels) {
                del_info.labels = [del_info.labels];
            }

            cb(null, {
                status: 200,
                article: del_info
            });
        }
    }));
}

ArticleDao.saveArticle = function (data, cb) {
    var sql = 'insert into article set ?';
    var value = {
        title: data.title,
        content: data.content,
        gist: data.gist,
        labels: data.labels,
        created_date: new Date(),
        status: 1,
        author: data.author,
        account: data.account,
        app_sid: data.app_sid
    };

    DBFactory.executeSql(sql, value, 'ArticleDao.saveArticle', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            cb(null, {
                status: 201,
                msg: '发表文章出现异常!'
            });
        } else {
            cb(null, {
                status: 200,
                msg: '发表文章成功!'
            });
        }
    }));
}

ArticleDao.saveContent = function (data, cb) {
    var sql = 'insert into article set ?';
    var value = {
        title: data.title,
        content: data.content,
        gist: data.gist,
        labels: data.labels,
        created_date: new Date(),
        status: 1,
        author: data.author,
        openid: data.openid,
        main_pic: data.main_pic,
        app_sid: 'nyl',
        avatar: data.avatar
    };

    DBFactory.executeSql(sql, value, 'ArticleDao.saveContent', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            return cb('发表文章出现异常!');
        }

        return cb(null, '发表文章成功!');
    }));
}

ArticleDao.addArticleComment = function (data, cb) {
    var sql = 'insert into article_comment set ?';
    var value = {
        article_id: data.article_id,
        comment: data.comment,
        created_date: new Date(),
        status: 1,
        author: data.username,
        account: data.account,
        app_sid: data.app_sid,
        avatar: data.avatar,
        openid: data.openid
    };

    DBFactory.executeSql(sql, value, 'ArticleDao.addArticleComment', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            cb(null, {
                status: 201,
                msg: '发表评论出现异常!'
            });
        } else {
            cb(null, {
                status: 200,
                msg: '发表评论成功!'
            });
        }
    }));
}

ArticleDao.updateArticle = function (data, cb) {
    var sql = 'update article set title = ?, content = ?, gist = ?, labels = ?, main_pic = ? where id = ?';
    var value = [data.title, data.content, data.gist, data.labels, data.main_pic, data.id];

    DBFactory.executeSql(sql, value, 'ArticleDao.updateArticle', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            cb(null, {
                status: 201,
                msg: '更新文章出现异常!'
            });
        } else {
            cb(null, {
                status: 200,
                msg: '更新文章成功!'
            });
        }
    }));
}

ArticleDao.deleteArticle = function (data, cb) {
    var sql = 'delete from article where id = ?';
    var value = [data];

    DBFactory.executeSql(sql, value, 'ArticleDao.deleteArticle', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            cb(null, {
                status: 201,
                msg: '删除文章出现异常!'
            });
        } else {
            cb(null, {
                status: 200,
                msg: '删除文章成功!'
            });
        }
    }));
}

ArticleDao.rand_article = function (data, cb) {
    var sql = 'SELECT * FROM article WHERE id >= ((SELECT MAX(id) FROM article) - (SELECT MIN(id) FROM article)) * RAND() + (SELECT MIN(id) FROM article) and status = 1 LIMIT 4';
    var value = [];

    DBFactory.executeSql(sql, value, 'ArticleDao.rand_article', autoCbErrFunction(cb, function (result) {
        if (!result[0]) {
            cb(null, {
                status: 201,
                msg: '查询文章出现异常!'
            });
        } else {
            cb(null, {
                status: 200,
                article: result
            });
        }
    }));
}

ArticleDao.addArticleStar = function (data, cb) {
    if (!data) {
        cb(new Error(500));
    } else {
        DBFactory.getConnection(function (error, connection) { //使用transaction进行转账
            if (error) {
                cb(error);
            } else {
                async.waterfall([
                    // 开始Transaction
                    function (callback) {
                        connection.beginTransaction(function (err) {
                            callback(err);
                        });
                    },
                    function (callback) {
                        var sql = 'select count(*) as count from article_stars where account = ? and app_sid = ? and article_id = ?';
                        var value = [data.account, data.app_sid, data.article_id];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                cb(null, {
                                    status: 201,
                                    msg: err
                                });
                            } else {
                                if (result[0].count == 0) {
                                    callback(null, {
                                        status: 200,
                                        msg: '用户未对本文章点赞！'
                                    });
                                } else {
                                    callback(null, {
                                        status: 201,
                                        msg: '用户已经点赞过本文章!'
                                    });
                                }
                            }
                        });
                    },
                    function (release_info, callback) {
                        if (release_info.status == 201) {
                            var sql = 'delete from article_stars where account = ? and app_sid = ? and article_id = ?';
                            var value = [data.account, data.app_sid, data.article_id];
                            connection.query(sql, value, function (err, result) {
                                if (err) {
                                    cb(null, {
                                        status: 201,
                                        msg: err
                                    });
                                } else {
                                    if (result.affectedRows == 0) {
                                        callback(null, {
                                            status: 201,
                                            msg: '取消点赞失败！'
                                        });
                                    } else {
                                        callback(null, {
                                            status: 201,
                                            msg: '取消点赞成功！'
                                        });
                                    }
                                }
                            });
                        } else if (release_info.status == 200) {
                            var sql = 'insert into article_stars set ?';
                            var value = {
                                account: data.account,
                                app_sid: data.app_sid,
                                article_id: data.article_id,
                                status: 1,
                                created_date: new Date(),
                                openid: data.openid
                            };

                            connection.query(sql, value, function (err, result) {
                                if (err) {
                                    cb(null, {
                                        status: 201,
                                        msg: err
                                    });
                                } else {
                                    if (result.affectedRows == 0) {
                                        callback(null, {
                                            status: 201,
                                            msg: '点赞失败，请联系管理员！'
                                        });
                                    } else {
                                        callback(null, {
                                            status: 200,
                                            msg: '点赞成功'
                                        });
                                    }
                                }
                            });
                        }
                    },
                    function (release_info, callback) {
                        var sql = 'select count(*) as count from article_stars where article_id = ?';
                        var value = [data.article_id];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                cb(null, {
                                    status: 201,
                                    msg: err
                                });
                            } else {
                                if (release_info.status == 200) {
                                    callback(null, true, {
                                        status: 200,
                                        msg: '点赞成功！',
                                        count: result[0].count
                                    });
                                } else {
                                    callback(null, true, {
                                        status: 201,
                                        msg: '取消点赞成功！',
                                        count: result[0].count
                                    });
                                }
                            }
                        });
                    }
                ], function (DbErr, isSuccess, uidOrInfo) {
                    if (DbErr || !isSuccess) {
                        connection.rollback(function () {
                            connection.release();
                        });

                        return cb(DbErr);
                    }

                    connection.commit(function (e) {
                        if (e) {
                            connection.rollback(function () {
                                connection.release();
                            });

                            return cb(e);
                        }

                        connection.release();
                        cb(null, uidOrInfo);
                    });
                });
            }
        });
    }
}

ArticleDao.wx_news = function (data, cb) {
    var param = {
        pno: 0,
        ps: 4,
        key: '61c397092ae5ea43c86a9c6f606851eb'
    }

    PostHelper.baseRequest('http://v.juhe.cn/weixin/query', param, function (err, result) {
        if (err) {
            return cb({
                status: 201,
                msg: err
            });
        } else {
            return cb(null, {
                status: 200,
                data: result
            });
        }
    });
}

ArticleDao.articleComments = function (data, cb) {
    if (!data) {
        cb(new Error(500));
    } else {
        DBFactory.getConnection(function (error, connection) {
            if (error) {
                cb(error);
            } else {
                async.waterfall([
                    // 开始Transaction
                    function (callback) {
                        connection.beginTransaction(function (err) {
                            callback(err);
                        });
                    },
                    function (callback) {
                        var sql = 'select article_id, account, app_sid, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date, author, comment, avatar from article_comment where article_id = ?';
                        var value = [data];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                return callback(err);
                            }

                            if (!result[0]) {
                                return callback('文章尚无评论!');
                            }

                            callback(null, true, {
                                status: 200,
                                article: result
                            });
                        });
                    }
                ], function (DbErr, isSuccess, uidOrInfo) {
                    if (DbErr || !isSuccess) {
                        connection.rollback(function () {
                            connection.release();
                        });

                        return cb(DbErr);
                    }

                    connection.commit(function (e) {
                        if (e) {
                            connection.rollback(function () {
                                connection.release();
                            });

                            return cb(e);
                        }

                        connection.release();
                        return cb(null, uidOrInfo);
                    });
                });
            }
        });
    }
}

ArticleDao.checkUserStar = function (data, cb) {
    if (!data) {
        cb(new Error(500));
    } else {
        DBFactory.getConnection(function (error, connection) {
            if (error) {
                cb(error);
            } else {
                async.waterfall([
                    // 开始Transaction
                    function (callback) {
                        connection.beginTransaction(function (err) {
                            callback(err);
                        });
                    },
                    function (callback) {
                        var sql = 'select * from article_stars where account = ? and app_sid = ? and article_id = ?';
                        var value = [data.account, data.app_sid, data.article_id];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                return callback(err);
                            }

                            if (!result[0]) {
                                return callback(null, {
                                    code: 0,
                                    msg: '用户未对本文章点赞！'
                                });
                            } else {
                                callback(null, {
                                    code: 1,
                                    msg: '用户已经点赞过本文章!'
                                });
                            }
                        });
                    },
                    function (info, callback) {
                        var sql = 'select count(*) as count from article_stars where article_id = ?';
                        var value = [data.article_id];
                        connection.query(sql, value, function (err, result) {
                            if (err) {
                                return callback(err);
                            }

                            info.star_count = result[0].count;

                            callback(null, true, info);
                        });
                    }
                ], function (DbErr, isSuccess, uidOrInfo) {
                    if (DbErr || !isSuccess) {
                        connection.rollback(function () {
                            connection.release();
                        });

                        return cb(DbErr);
                    }

                    connection.commit(function (e) {
                        if (e) {
                            connection.rollback(function () {
                                connection.release();
                            });

                            return cb(e);
                        }

                        connection.release();
                        cb(null, uidOrInfo);
                    });
                });
            }
        });
    }
}

ArticleDao.checkUserRead = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'select * from article_read where account = ? and app_sid = ? and article_id = ?';
                var value = [data.account, data.app_sid, data.article_id];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback(null, 200);
                    }

                    return callback('用户已经阅读过本文章!');
                });
            },
            function (info, callback) {
                var sql = 'insert into article_read set ?';
                var value = {
                    account: data.account,
                    app_sid: data.app_sid,
                    article_id: data.article_id,
                    status: 1,
                    created_date: new Date()
                };

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        callback('添加阅读记录异常！');
                    }

                    return callback(null, 200);
                });
            },
            function (info, callback) {
                var sql = 'update article set read_count = read_count + 1 where id = ?';

                connection.query(sql, [data.article_id], function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        callback('添加阅读次数异常！');
                    }

                    return callback(null, true, 200);
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.userDesignArticle = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            //通过article_id获取作者发布的所有文章
            function (callback) {
                var sql = 'select id, title, content, gist, labels, author, openid, app_sid, read_count, main_pic, avatar, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date from article where openid = (select openid from article where id = ?)';
                var value = [data.article_id];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback(null, {
                            code: 0,
                            data: []
                        });
                    }

                    return callback(null, {
                        code: 1,
                        data: result
                    });
                });
            },

            //获取文章标签
            function (info, callback) {
                var sql = 'select labels from article where labels is not null group by labels';
                var value = [];
                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    callback(null, {
                        data: info.data,
                        labels: result
                    });
                });
            },

            //判断是否为自己添加自己为好友
            function (info, callback) {
                var sql = 'select account from users where openid = ?';
                var value = [data.openid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (data.myphone == result[0].account) {
                        return callback(null, {
                            isFriend: true,
                            data: info.data,
                            labels: info.labels
                        });
                    }

                    return callback(null, {
                        isFriend: false,
                        data: info.data,
                        labels: info.labels
                    });
                });
            },

            //判断是否为好友关系
            function (info, callback) {
                if (info.isFriend) {
                    return callback(null, true, info);
                }

                var sql = 'select * from user_relationship where myphone = ? and friendphone = (select account from users where openid = ?)';
                var value = [data.myphone, data.openid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0] || result[0].status != 1) {
                        return callback(null, true, {
                            isFriend: false,
                            data: info.data,
                            labels: info.labels
                        });
                    }

                    return callback(null, true, {
                        isFriend: true,
                        data: info.data,
                        labels: info.labels
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.addUserApply = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            //判断是否已经提交好友申请
            function (callback) {
                var sql = 'select count(*) as count from add_user_apply where status = 1 and myphone = ? and friendphone = (select account from users where openid = ?)';
                var value = [data.myphone, data.openid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result[0].count == 0) {
                        return callback(null, 200);
                    }

                    return callback('已提交好友申请!');
                });
            },

            //通过openid查询作者账号
            function (info, callback) {
                var sql = 'select account from users where openid = ?';
                var value = [data.openid];
                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result[0].account == data.myphone) {
                        return callback('不能添加自己为好友!');
                    }

                    data.friendphone = result[0].account;

                    return callback(null, 200);
                });
            },

            //创建好友申请
            function (info, callback) {
                var sql = 'insert into add_user_apply set ?';
                var value = {
                    myphone: data.myphone,
                    friendphone: data.friendphone,
                    app_sid: data.app_sid,
                    status: 1,
                    created_date: new Date()
                };

                data.comment ? value.comment = data.comment : '';

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        return callback('添加好友出现异常!');
                    }

                    return callback(null, true, '发送好友申请成功!');
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getUserMessage = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'SELECT id, myphone, friendphone, status, comment, app_sid, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date FROM add_user_apply WHERE friendphone = ? and app_sid = ?';
                var value = [data.account, data.app_sid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback('暂无好友申请!');
                    }

                    return callback(null, result);
                });
            },

            //通过myphone查询读者头像以及用户名
            function (info, callback) {

                var resultInfo = [];
                info.forEach(user => {
                    var sql = 'select username, avatar, city, province from users where account = ? and app_sid = ?';
                    var value = [user.myphone, user.app_sid];
                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        if (!result[0]) {
                            return callback('用户不存在!');
                        }

                        user.username = result[0].username;
                        user.avatar = result[0].avatar;
                        user.city = result[0].city;
                        user.province = result[0].province;
                        resultInfo.push(user);

                        if (info.length == resultInfo.length) {
                            callback(null, true, resultInfo);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getCommentMessage = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'SELECT article_id, account, app_sid, comment, author, avatar, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date FROM article_comment WHERE openid = (select openid from users where account = ? and app_sid = ?)';
                var value = [data.account, data.app_sid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback('暂未有新评论!');
                    }

                    return callback(null, result);
                });
            },

            //通过myphone查询读者头像以及用户名
            function (info, callback) {

                var resultInfo = [];
                info.forEach(user => {
                    var sql = 'select username, avatar, city, province from users where account = ? and app_sid = ?';
                    var value = [user.account, user.app_sid];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        if (!result[0]) {
                            return callback('用户不存在!');
                        }

                        user.username = result[0].username;
                        user.avatar = result[0].avatar;
                        user.city = result[0].city;
                        user.province = result[0].province;
                        resultInfo.push(user);

                        if (info.length == resultInfo.length) {
                            return callback(null, true, resultInfo);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getStarMessage = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'SELECT article_id, account, app_sid, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date FROM article_stars WHERE openid = (select openid from users where account = ? and app_sid = ?)';
                var value = [data.account, data.app_sid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback('暂未有新评论!');
                    }

                    return callback(null, result);
                });
            },

            //通过myphone查询读者头像以及用户名
            function (info, callback) {

                var resultInfo = [];
                info.forEach(user => {
                    var sql = 'select username, avatar, city, province from users where account = ? and app_sid = ?';
                    var value = [user.account, user.app_sid];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        if (!result[0]) {
                            return callback('用户不存在!');
                        }

                        user.username = result[0].username;
                        user.avatar = result[0].avatar;
                        user.city = result[0].city;
                        user.province = result[0].province;
                        resultInfo.push(user);

                        if (info.length == resultInfo.length) {
                            return callback(null, true, resultInfo);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.refuseApply = function (data, cb) {
    var sql = 'update add_user_apply set status = 3 where id = ?';
    var value = [data.id];

    DBFactory.executeSql(sql, value, 'ArticleDao.rand_article', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            return cb('审批好友申请出现异常!');
        }

        return cb(null, '拒绝好友申请成功!');
    }));
}

ArticleDao.deleteFriend = function (data, cb) {
    var sql = 'delete from user_relationship where id = ?';
    var value = [data.id];

    DBFactory.executeSql(sql, value, 'ArticleDao.rand_article', autoCbErrFunction(cb, function (result) {
        if (result.affectedRows == 0) {
            return cb('删除好友出现异常!');
        }

        return cb(null, '删除好友成功!');
    }));
}

ArticleDao.consentApply = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'update add_user_apply set status = 2 where id = ?';
                var value = [data.id];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        return callback('审批好友申请出现异常!');
                    }

                    return callback(null, 200);
                });
            },

            //创建好友关系
            function (info, callback) {
                var sql = 'insert into user_relationship set ?';
                var value = {
                    myphone: data.myphone,
                    friendphone: data.friendphone,
                    special_focus: 0,
                    status: 1,
                    created_date: new Date()
                };

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        return callback('创建好友关系出现异常!');
                    }

                    return callback(null, 200);
                });
            },

            //创建好友关系
            function (info, callback) {
                var sql = 'insert into user_relationship set ?';
                var value = {
                    myphone: data.friendphone,
                    friendphone: data.myphone,
                    special_focus: 0,
                    status: 1,
                    created_date: new Date()
                };

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result.affectedRows == 0) {
                        return callback('创建好友关系出现异常!');
                    }

                    return callback(null, true, '已同意申请!');
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getFriendList = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            function (callback) {
                var sql = 'select * from user_relationship where myphone = ?';
                var value = [data.account, data.app_sid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback('还未添加过好友!');
                    }

                    return callback(null, result);
                });
            },

            function (info, callback) {
                var resultInfo = [];
                info.forEach(user => {
                    var sql = 'select username, avatar, city, province, openid from users where account = ? and app_sid = ?';
                    var value = [user.friendphone, data.app_sid];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        if (!result[0]) {
                            return callback('用户不存在!');
                        }

                        user.username = result[0].username;
                        user.avatar = result[0].avatar;
                        user.city = result[0].city;
                        user.province = result[0].province;
                        user.openid = result[0].openid;
                        resultInfo.push(user);

                        if (info.length == resultInfo.length) {
                            return callback(null, true, resultInfo);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getUserArticleAndCategories = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            //获取用户发布的所有文章
            function (callback) {
                var sql = 'select id, title, content, gist, labels, author, openid, app_sid, read_count, main_pic, avatar, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date from article where openid = ? and app_sid = ?';
                var value = [data.openid, data.app_sid];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback(null, {
                            code: 0,
                            data: []
                        });
                    }

                    return callback(null, {
                        code: 1,
                        data: result
                    });
                });
            },
            function (release_info, callback) {
                if (release_info.code == 0) {
                    return callback(null, release_info);
                }

                var info = [];
                release_info.data.forEach(article => {
                    var sql = 'select count(*) as count from article_stars where article_id = ?';
                    var value = [article.id];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article.starsCount = result[0].count;
                        info.push(article);

                        if (info.length == release_info.data.length) {
                            return callback(null, {
                                code: 1,
                                data: info
                            });
                        }
                    });
                });

            },
            function (release_info, callback) {
                if (release_info.code == 0) {
                    return callback(null, release_info);
                }

                var info = [];
                release_info.data.forEach(article => {
                    var sql = 'select count(*) as count from article_comment where article_id = ?';
                    var value = [article.id];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article.CommentCount = result[0].count;
                        info.push(article);

                        if (info.length == release_info.data.length) {
                            return callback(null, {
                                code: 1,
                                data: info
                            });
                        }
                    });
                });
            },

            //获取文章标签
            function (info, callback) {
                var sql = 'select labels from article where labels is not null group by labels';
                var value = [];
                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    callback(null, true, {
                        data: info.data,
                        labels: result
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getLabelsArticle = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            //获取用户发布的所有文章
            function (callback) {
                var sql = 'select id, title, content, gist, labels, author, openid, app_sid, read_count, main_pic, avatar, DATE_FORMAT(created_date, "%Y-%m-%d %H:%i:%s") as created_date from article where openid = ? and app_sid = ? and labels = ?';
                var value = [data.openid, data.app_sid, data.cateUrl];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (!result[0]) {
                        return callback('该分类还未发表文章!');
                    }

                    return callback(null, result);
                });
            },
            function (release_info, callback) {

                var info = [];
                release_info.forEach(article => {
                    var sql = 'select count(*) as count from article_stars where article_id = ?';
                    var value = [article.id];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article.starsCount = result[0].count;
                        info.push(article);

                        if (info.length == release_info.length) {
                            return callback(null, info);
                        }
                    });
                });
            },
            function (release_info, callback) {
                var info = [];
                release_info.forEach(article => {
                    var sql = 'select count(*) as count from article_comment where article_id = ?';
                    var value = [article.id];

                    connection.query(sql, value, function (err, result) {
                        if (err) {
                            return callback(err);
                        }

                        article.CommentCount = result[0].count;
                        info.push(article);

                        if (info.length == release_info.length) {
                            return callback(null, true, info);
                        }
                    });
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}

ArticleDao.getFriendInfo = function (data, cb) {
    var sql = 'select account, username, avatar, city, province, openid from users where account = ? and app_sid = ?';
    var value = [data.account, data.app_sid];

    DBFactory.executeSql(sql, value, 'ArticleDao.rand_article', autoCbErrFunction(cb, function (result) {
        if (!result[0]) {
            return cb('用户不存在!');
        }

        return cb(null, result[0]);
    }));
}

ArticleDao.checkIsFriend = function (data, cb) {
    DBFactory.getConnection(function (error, connection) {
        if (error) {
            return cb(error);
        }

        async.waterfall([
            function (callback) {
                connection.beginTransaction(function (err) {
                    return callback(err);
                });
            },
            //获取用户发布的所有文章
            function (callback) {
                var sql = 'select count(*) as count from user_relationship where myphone = ? and friendphone = ? and status = 1';
                var value = [data.myphone, data.friendphone];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result[0].count == 0) {
                        return callback('未成为好友!');
                    }

                    return callback(null, 200);
                });
            },
            function (release_info, callback) {

                var sql = 'select count(*) as count from user_relationship where myphone = ? and friendphone = ? and status = 1';
                var value = [data.friendphone, data.myphone];

                connection.query(sql, value, function (err, result) {
                    if (err) {
                        return callback(err);
                    }

                    if (result[0].count == 0) {
                        return callback('未成为好友!');
                    }

                    return callback(null, true, "已经成为好友!");
                });
            }
        ], function (DbErr, isSuccess, uidOrInfo) {
            if (DbErr || !isSuccess) {
                connection.rollback(function () {
                    connection.release();
                });

                return cb(DbErr);
            }

            connection.commit(function (e) {
                if (e) {
                    connection.rollback(function () {
                        connection.release();
                    });

                    return cb(e);
                }

                connection.release();
                cb(null, uidOrInfo);
            });
        });
    });
}